C#でPDFを生成する場合、実務で最も使われるのが QuestPDF と iText の2つです。 請求書・納品書・検査成績書・一覧レポートなど、 業務アプリでは欠かせない機能です。
この記事でわかること
・QuestPDFとiTextの違い
・PDFの基本生成(テキスト・画像・表)
・ヘッダー/フッター・ページ番号
・帳票レイアウトの作り方
・テンプレート方式
・大量PDFのバッチ出力
・業務アプリ向けベストプラクティス
・QuestPDFとiTextの違い
・PDFの基本生成(テキスト・画像・表)
・ヘッダー/フッター・ページ番号
・帳票レイアウトの作り方
・テンプレート方式
・大量PDFのバッチ出力
・業務アプリ向けベストプラクティス
1. QuestPDF と iText の違い
| 項目 | QuestPDF | iText |
|---|---|---|
| 特徴 | モダン・書きやすい・レイアウト強い | 高機能・歴史が長い |
| 商用利用 | 無料(OSS) | 商用ライセンス必要 |
| レイアウト | CSS風で直感的 | 細かい制御が可能 |
| 帳票向け | ◎(最適) | ○(高機能) |
帳票・レポート → QuestPDF 特殊PDF・電子署名 → iText
2. QuestPDFでPDFを生成する(最も実務的)
■ 2-1. 基本のPDF生成
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
Document.Create(container =>
{
container.Page(page =>
{
page.Margin(40);
page.Content().Text("Hello PDF!");
});
})
.GeneratePdf("sample.pdf");
■ 2-2. テキスト・画像・表の配置
page.Content().Column(col =>
{
col.Item().Text("請求書").FontSize(24).Bold();
col.Item().Image("logo.png");
col.Item().Table(table =>
{
table.ColumnsDefinition(c =>
{
c.ConstantColumn(100);
c.RelativeColumn();
c.ConstantColumn(80);
});
table.Header(h =>
{
h.Cell().Text("商品");
h.Cell().Text("説明");
h.Cell().Text("金額");
});
foreach (var item in items)
{
table.Cell().Text(item.Name);
table.Cell().Text(item.Description);
table.Cell().Text($"{item.Price:#,##0} 円");
}
});
});
■ 2-3. ヘッダー・フッター・ページ番号
page.Header().Text("株式会社サンプル").FontSize(12);
page.Footer().AlignRight().Text(x =>
{
x.Span("Page ");
x.CurrentPageNumber();
x.Span(" / ");
x.TotalPages();
});
3. iTextでPDFを生成する(高機能)
■ 3-1. 基本のPDF生成
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using var writer = new PdfWriter("sample.pdf");
using var pdf = new PdfDocument(writer);
var doc = new Document(pdf);
doc.Add(new Paragraph("Hello PDF!"));
doc.Close();
■ 3-2. テーブルの作成
var table = new Table(3);
table.AddHeaderCell("商品");
table.AddHeaderCell("説明");
table.AddHeaderCell("金額");
foreach (var item in items)
{
table.AddCell(item.Name);
table.AddCell(item.Description);
table.AddCell($"{item.Price:#,##0} 円");
}
doc.Add(table);
■ 3-3. 画像挿入
var img = new Image(ImageDataFactory.Create("logo.png"));
doc.Add(img);
4. 帳票レイアウトの作り方(請求書・納品書)
帳票は「紙のレイアウト」を先に決めてからPDFに落とすと安定します。
■ レイアウト構成例
- ヘッダー:会社名・ロゴ・発行日
- 宛先:顧客名・住所
- 明細テーブル:商品・数量・単価・金額
- 合計:小計・税・総額
- 備考欄
- フッター:ページ番号・署名欄
QuestPDFはこの構成をそのままコードに落としやすいです。
5. テンプレート方式(実務で最強)
帳票は「テンプレートPDF」を読み込み、 差し込み項目だけ埋める方式が最も安定します。
■ テンプレートPDFに文字を差し込む(iText)
var pdf = new PdfDocument(new PdfReader("template.pdf"), new PdfWriter("output.pdf"));
var form = PdfAcroForm.GetAcroForm(pdf, true);
form.GetField("CustomerName").SetValue("山田太郎");
form.GetField("TotalAmount").SetValue("123,456 円");
pdf.Close();
請求書・契約書など、固定レイアウトに最適。
6. 大量PDFのバッチ出力(100件〜1,000件)
大量PDFを生成する場合は、 非同期処理+進捗表示+キャンセル対応が必須です。
■ バッチ出力の流れ
- 対象データをSQLiteから取得
- 1件ずつPDF生成
- フォルダに保存(顧客コード・日付で命名)
- ZIP圧縮して配布
■ 非同期処理例(WPF/MVVM)
public async Task ExportAllAsync()
{
IsBusy = true;
var list = await _repo.GetInvoicesAsync();
int total = list.Count;
int current = 0;
foreach (var invoice in list)
{
await _pdfService.ExportAsync(invoice);
current++;
Progress = (int)(current * 100.0 / total);
}
IsBusy = false;
}
7. 業務アプリ向けベストプラクティス
- 帳票 → QuestPDF(書きやすい・レイアウト強い)
- 電子署名・特殊PDF → iText
- テンプレートPDF方式は現場で最も安定
- 大量出力は非同期+進捗表示
- ファイル名は「顧客コード_日付.pdf」で一意に
- レポート用DTOを作り、PDFロジックと分離する
まとめ:PDF生成は“業務アプリの価値を上げる”最強機能
- QuestPDF → モダンで帳票向け
- iText → 高機能で特殊用途に強い
- テンプレート方式 → 安定・保守性◎
- 非同期処理でUIフリーズを防ぐ
「画面で見えるものを、そのままPDFにしたい」 という現場の声に応えるために、 QuestPDFとiTextを使いこなしてみてください。